package io.vector.study.concurrent.sync;

import io.vector.study.concurrent.util.Threads;
import lombok.Getter;
import lombok.Setter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Created by vector on 2017/3/10.
 */
@Getter
@Setter
public class SyncTestModel {

    private static final Logger logger = LoggerFactory.getLogger(SyncTestModel.class);

    private Integer id = 0;

    private String name = "";

    private static final Object lock = new Object();

    public static synchronized void staticSyncMethod() {
        logger.info("static synchronized method start...");
        Threads.sleepOneSecond();
        logger.info("static synchronized method end...");
    }

    public synchronized void setNameWithMethodSync(String name) {
        setNameAndSleepOneSecond(name);
    }

    public void setNameWithStaticFieldSync(String name) {
        synchronized (lock) {
            setNameAndSleepOneSecond(name);
        }
    }

    public void setNameWithClassSync(String name) {
        synchronized (SyncTestModel.class) {
            setNameAndSleepOneSecond(name);
        }
    }

    public void setNameWithObjectSync(String name) {
        synchronized (this) {
            setNameAndSleepOneSecond(name);
        }
    }

    public void setNameWithPropertySync(String name) {
        synchronized (this.name) {
            setNameAndSleepOneSecond(name);
        }
    }

    public void setIdWithPropertySync(String name) {
        synchronized (this.id) {
            setNameAndSleepOneSecond(name);
        }
    }

    public synchronized void displayNameWithMethodSync() {
        displayName();
    }

    public synchronized void displayNameWithPropertySync() {
        synchronized (this.name) {
            displayName();
        }
    }

    public synchronized void displayIdWithPropertySync() {
        synchronized (this.id) {
            displayName();
        }
    }

    public void setNameAndSleepOneSecond(String name) {
        logger.info("set method start... " + name);
        Threads.sleepOneSecond();
        setName(name);
        logger.info("set method end... "  + name);
    }

    public void setIdAndSleepOneSecond(Integer id) {
        logger.info("set method start...");
        Threads.sleepOneSecond();
        setId(id);
        logger.info("set method end...");
    }

    public void displayName() {
        logger.info("display method start...");
        logger.info("display method end...");
    }

}
